<template>
  <div v-if="visible" class="gis-modal-draggabilly position-left" @click.stop>
    <div class="gis-modal-header">
      <span>统计分析</span>
      <span class="close-icon" @click="close">
        <a-icon-font type="iconicon-beifen1" />
      </span>
    </div>
    <div class="gis-modal-content">
      <div class="prompt-information">
        <span class="prompt-text">注：统计分析属性值</span>
        <a-popover
          :overlay-class-name="'gis-analysis-tool-help'"
          placement="topRight"
        >
          <template slot="content">
            <div class="help-popover-title">统计分析</div>
            <div class="help-popover-text">
              统计分析各要素的属性值的最大值、最小值、平均值、等统计信息。
            </div>
          </template>
          <div class="prompt-help">
            <a-icon-font type="iconbangzhu" />
          </div>
        </a-popover>
      </div>
      <a-row :gutter="[0, 6]">
        <a-col span="8">图层：</a-col>
        <a-col span="16">
          <div
            :title="selectLayer ? selectLayer.name : ''"
            class="setting-content text-overflow-ellipsis"
          >
            {{ selectLayer ? selectLayer.name : '-- 请选择图层 --' }}
          </div>
        </a-col>
      </a-row>
      <a-row :gutter="[0, 6]">
        <a-col span="8">范围：</a-col>
        <a-col span="16">
          <a-select v-model="scopeOfAnalysis" style="width: 100%;" size="small">
            <a-select-option value="all">
              全量数据
            </a-select-option>
          </a-select>
        </a-col>
      </a-row>
      <a-row :gutter="[0, 6]">
        <a-col span="8">属性：</a-col>
        <a-col span="16">
          <a-icon
            v-if="optionLoading"
            class="options-loading"
            type="sync"
            spin
          />
          <a-select
            v-model="attribute"
            style="width: 100%;"
            size="small"
            @change="attributeHandleChange"
          >
            <a-select-option
              v-for="item in layerAttributes"
              :key="item.col"
              :value="item.col"
              :title="item.col"
            >
              {{ item.col }}
            </a-select-option>
          </a-select>
        </a-col>
      </a-row>

      <!-- 筛选 -->
      <a-row :gutter="[0, 6]">
        <a-col span="8">筛选：</a-col>
        <a-col span="7">
          <div style="width: 100%;">
            <a-select
              v-model="filterAttribute"
              style="width: 100%;"
              size="small"
              @change="filterAttributeChange"
            >
              <a-select-option
                v-for="(item1, index) in filterAttributeOptions"
                :key="item1.value + index"
                :value="item1.value"
                :title="item1.text"
              >
                {{ item1.text }}
              </a-select-option>
            </a-select>
          </div>
        </a-col>
        <a-col span="2"> <a-icon-font type="iconjianhao" /> </a-col>
        <a-col span="7">
          <div style="width: 100%;">
            <a-select v-model="filterValue" style="width: 100%;" size="small">
              <a-select-option
                v-for="(item, index) in filterValueOptions"
                :key="item.value + index"
                :value="item.value"
                :title="item.text"
              >
                {{ item.text }}
              </a-select-option>
            </a-select>
          </div>
        </a-col>
      </a-row>
      <a-row :gutter="[0, 6]">
        <a-col span="8">精度：</a-col>
        <a-col span="16">
          <a-select v-model="resultPrecision" style="width: 100%;" size="small">
            <a-select-option
              v-for="(item, index) in precisionOptions"
              :key="index"
              :value="item"
            >
              {{ item }}
            </a-select-option>
          </a-select>
        </a-col>
      </a-row>

      <!-- 时间单位 -->
      <a-row v-show="attributeType === 91" :gutter="[0, 6]">
        <a-col span="8">时间单位：</a-col>
        <a-col span="16">
          <a-select v-model="unitOfTime" style="width: 100%;" size="small">
            <a-select-option
              v-for="item in unitOfTimeOptions"
              :key="item.key"
              :value="item.key"
            >
              {{ item.name }}
            </a-select-option>
          </a-select>
        </a-col>
      </a-row>
    </div>

    <div class="statistical-results gray-background">
      <a-row :gutter="[0, 6]">
        <a-col span="24" class="result-title">统计结果</a-col>
      </a-row>
      <a-row
        v-for="(result, index) in analysisResult"
        :key="result.name + index"
        :gutter="[0, 6]"
      >
        <div v-show="result.value">
          <a-col span="8">{{ result.name }}：</a-col>
          <a-col span="16">
            <div class="text-overflow-ellipsis">
              {{ result.value }}
            </div>
          </a-col>
        </div>
      </a-row>
    </div>

    <div class="button-row">
      <a-button class="op-btn-sub" size="small" @click="close">取消</a-button>
      <a-button
        :disabled="checkParams"
        :loading="iconLoading"
        class="op-btn-sub"
        type="primary"
        size="small"
        @click="doOption"
      >
        计算
      </a-button>
    </div>
  </div>
</template>

<script lang="ts">
/**
 * 数理分析
 */
import { Component, Watch, Vue, Prop } from 'vue-property-decorator'
import GisStore from '@/store/modules/gis'
import Draggabilly from 'draggabilly'

const allAttribute: string = 'ALL_ATTRIBUTE__' // 筛选字段全部
const allFilterValue: string = 'ALL_VALVE__' // 筛选值全部

@Component({
  components: {},
})
export default class MathematicalAnalysis extends Vue {
  @Prop({ type: Boolean, default: false }) visible!: boolean
  public drag: any = null
  public scopeOfAnalysis: string = 'all' // 范围
  public attribute: string = '' // 属性
  // 图层可选属性
  public get layerAttributes(): { col: string; type: string }[] {
    return Object.keys(this.getColTypesParams?.colTypes).map((key: string) => {
      return {
        col: key,
        type: this.getColTypesParams?.colTypes[key],
      }
    })
  }
  public attributeType: any = null // 属性类型 3-数值， 12-string 91-date
  private filterAttribute: string = '' // 筛选字段
  // 筛选字段选项
  private get filterAttributeOptions(): { value: string; text: string }[] {
    let options: { value: string; text: string }[] = [
      { value: allAttribute, text: '全部' },
    ]
    if (this.getColTypesParams?.filterCols) {
      const selectableFilterAttribute: string[] = Object.keys(
        this.getColTypesParams.filterCols
      ).filter((key1: string) => key1 !== 'geom' && key1 !== 'geom_4326')
      options = [
        ...options,
        ...selectableFilterAttribute.map((item: any) => {
          return {
            value: item,
            text: item,
          }
        }),
      ]
    }
    return options
  }
  private filterValue: string = '' // 筛选字段对应值
  // 筛选字段对应值选项
  private get filterValueOptions(): { value: string; text: string }[] {
    let options: { value: string; text: string }[] = [
      { value: allFilterValue, text: '全部' },
    ]
    if (
      this.filterAttribute !== allAttribute &&
      this.getColTypesParams?.filterCols[this.filterAttribute]
    ) {
      options = [
        ...options,
        ...this.getColTypesParams?.filterCols[this.filterAttribute]?.map(
          (item: any) => {
            return {
              value: item,
              text: item,
            }
          }
        ),
      ]
    }
    return options
  }
  private filterValueLoading: boolean = false // 筛选属性值 loading
  public resultPrecision: number = 5 // 结果精度
  // 精度选项
  private precisionOptions: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  // 项目 id
  private get projectId() {
    return GisStore.projectId
  }
  private optionLoading: boolean = false // 可选属性加载
  public iconLoading: any = false // 计算 loading
  private unitOfTime: string = 'd' // 时间单位
  private unitOfTimeOptions: { key: string; name: string }[] = [
    { key: 's', name: '秒' },
    { key: 'm', name: '分' },
    { key: 'h', name: '时' },
    { key: 'd', name: '日' },
    { key: 'M', name: '月' },
    { key: 'y', name: '年' },
  ] // 时间单位选项
  // 分析结果
  public analysisResult: any = {
    maxRes: { name: '最大值', value: '--' },
    minRes: { name: '最小值', value: '--' },
    avgRes: { name: '平均值', value: '--' },
    diffRes: { name: '差值', value: '--' },
    distinctCount: { name: '去重计数', value: '--' },
  }

  public getColTypesParams: { colTypes?: any; filterCols?: any } = {
    colTypes: {},
    filterCols: {},
  }

  public get selectLayer() {
    return GisStore.selectLayer
  }

  @Watch('selectLayer', { deep: true })
  private watchSelectLayer(layer: any) {
    if (layer && this.visible) {
      this.clearResult()
      this.queryAttributesOptions(layer.id)
    }
  }

  /**
   * 属性获取
   * @param layerId
   */
  public async queryAttributesOptions(layerId: number) {
    const parameters: any = {
      projectId: this.projectId,
      layerId,
    }
    this.optionLoading = true
    const response: any = await GisStore.querySelectableAttributesByLayerId(
      parameters
    )
    this.optionLoading = false
    if (response.data.code === 100) {
      this.getColTypesParams = response.data.result
      const { colTypes } = response.data.result
      ;[this.attribute] = Object.keys(colTypes)
      ;[this.attributeType] = Object.values(colTypes)
      this.filterAttribute = allAttribute
      // 神奇， 需要$nextTick
      this.$nextTick(() => {
        this.filterValue = allFilterValue
      })
    }
  }

  /**
   * 切换属性
   * @param value
   */
  private attributeHandleChange(value: any) {
    const selectAttribute: any = this.layerAttributes.find(
      ({ col }) => col === value
    )
    if (selectAttribute) {
      this.attributeType = selectAttribute.type
    }
  }

  public filterAttributeChange() {
    this.filterValue = allFilterValue
  }

  @Watch('visible', { immediate: true })
  private watchVisible(value: boolean) {
    const that = this
    if (value) {
      if (this.selectLayer) {
        this.clearResult()
        this.queryAttributesOptions(this.selectLayer.id)
      }
      setTimeout(() => {
        const $overlay = document.querySelector(
          '.gis-map-component'
        ) as HTMLDivElement
        const $element = document.querySelector(
          '.gis-modal-draggabilly'
        ) as HTMLDivElement
        that.drag = new Draggabilly($element, {
          containment: $overlay,
          grid: [1, 1],
        })
      }, 200)
    } else {
      this.clearResult()
    }
  }

  public get checkParams() {
    return this.attributeType !== 91
      ? !this.selectLayer?.id || !this.attribute
      : !this.selectLayer?.id ||
          !this.attribute ||
          !this.filterAttribute ||
          (!(this.filterAttribute !== allAttribute) && !this.filterValue)
  }

  public clearResult() {
    this.attribute = ''
    this.analysisResult.maxRes.value = '--'
    this.analysisResult.minRes.value = '--'
    this.analysisResult.avgRes.value = '--'
    this.analysisResult.diffRes.value = '--'
    this.analysisResult.distinctCount.value = '--'
  }

  /**
   * 数理分析计算
   */
  public async doOption() {
    const parameters: any = {
      projectId: this.projectId,
      layerId: this.selectLayer.id,
      col: this.attribute,
      precision: this.resultPrecision,
    }
    if (
      this.filterAttribute !== allAttribute &&
      this.filterValue !== allFilterValue
    ) {
      parameters.filterCol = this.filterAttribute // 过滤属性
      parameters.filterVals = [this.filterValue] // 过滤属性值
    }
    if (this.attributeType === 91) {
      parameters.dateUnit = this.unitOfTime
    }
    this.iconLoading = { delay: 1000 }
    await GisStore.getNumericalResponseApiByLayerId(parameters)
      .then((response: any) => {
        if (response.data.code === 100) {
          const {
            maxRes,
            minRes,
            avgRes,
            diffRes,
            distinctCount,
          } = response.data.result
          this.analysisResult.maxRes.value = maxRes
          this.analysisResult.minRes.value = minRes
          this.analysisResult.avgRes.value = avgRes
          this.analysisResult.diffRes.value = diffRes
          this.analysisResult.distinctCount.value = distinctCount
        }
      })
      .finally(() => {
        this.iconLoading = false
      })
  }

  public close() {
    GisStore.setCurrentToolBarAction(null)
  }
}
</script>

<style scoped lang="less">
@import '@/styles/common-style.less';
@import './analysis-drag-modal.less';

.position-left {
  left: 185px;
}
</style>
